import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    user: null,
    token: localStorage.getItem('token') || '',
    videos: [],
    currentVideoIndex: 0,
    viewedVideos: new Set(), // 存储已观看视频的ID
  },
  getters: {
    isLoggedIn: state => !!state.token,
    currentUser: state => state.user,
    currentVideo: state => state.videos[state.currentVideoIndex] || null,
    hasNextVideo: state => state.currentVideoIndex < state.videos.length - 1,
    hasPrevVideo: state => state.currentVideoIndex > 0
  },
  mutations: {
    SET_TOKEN(state, token) {
      state.token = token
      localStorage.setItem('token', token)
    },
    CLEAR_TOKEN(state) {
      state.token = ''
      localStorage.removeItem('token')
    },
    SET_USER(state, user) {
      state.user = user
    },
    SET_VIDEOS(state, videos) {
      state.videos = videos
    },
    ADD_VIEWED_VIDEO(state, videoId) {
      state.viewedVideos.add(videoId)
    },
    SET_CURRENT_VIDEO_INDEX(state, index) {
      state.currentVideoIndex = index
    },
    NEXT_VIDEO(state) {
      if (state.currentVideoIndex < state.videos.length - 1) {
        state.currentVideoIndex++
      }
    },
    PREV_VIDEO(state) {
      if (state.currentVideoIndex > 0) {
        state.currentVideoIndex--
      }
    },
    TOGGLE_FAVORITE(state, { videoId, isFavorite }) {
      const video = state.videos.find(v => v.id === videoId)
      if (video) {
        // 只更新点赞状态，不更新点赞数
        // 点赞数已经在组件中通过乐观更新处理
        video.is_favorite = isFavorite
      }
    }
  },
  actions: {
    // 用户登录
    async login({ commit }, { username, password }) {
      try {
        const params = new URLSearchParams()
        params.append('username', username)
        params.append('password', password)

        const res = await axios.post('/douyin/user/login/', params, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        })

        // 检查响应数据是否符合预期
        if (!res.data || res.data.status_code !== 0) {
          throw new Error(res.data?.status_msg || '登录失败，请稍后再试')
        }

        // 直接获取token
        const token = res.data.token;

        // 处理user_id，确保以字符串形式保存，避免精度丢失
        let userId;

        // 先检查是否已经是字符串
        if (typeof res.data.user_id === 'string') {
          userId = res.data.user_id;
          console.log('用户ID已经是字符串:', userId);
        } else {
          console.log('原始用户ID数值类型:', res.data.user_id, typeof res.data.user_id);

          // 尝试多种方法确保拿到正确的user_id
          try {
            // 方法1: 直接转换为字符串
            const directString = String(res.data.user_id);
            console.log('直接转换的用户ID:', directString);

            // 方法2: 尝试从原始响应中提取
            // 注意：这不一定有效，因为axios可能已经解析了响应
            let rawUserId = res.data.user_id;

            // 方法3: 从token JWT中解析用户ID（如果token包含用户信息）
            let tokenUserId = null;
            try {
              // 尝试从JWT token中解析用户信息
              const tokenParts = token.split('.');
              if (tokenParts.length === 3) {
                const payload = JSON.parse(atob(tokenParts[1]));
                if (payload.loginUser) {
                  const userInfo = JSON.parse(payload.loginUser);
                  if (userInfo.id) {
                    tokenUserId = String(userInfo.id);
                    console.log('从token解析的用户ID:', tokenUserId);
                  }
                }
              }
            } catch (tokenError) {
              console.error('解析token失败:', tokenError);
            }

            // 选择最可靠的用户ID
            userId = tokenUserId || directString;
            console.log('最终使用的用户ID:', userId);
          } catch (e) {
            console.error('转换用户ID时出错:', e);
            // 退回到基本的转换方法
            userId = String(res.data.user_id);
          }
        }

        // 验证token和userId是否存在
        if (!token || !userId) {
          throw new Error('登录失败：无效的用户凭证')
        }

        // 保存token和用户ID
        commit('SET_TOKEN', token)
        localStorage.setItem('user_id', userId)
        console.log('登录成功，已保存用户ID:', userId)

        try {
          // 获取用户信息
          const userRes = await axios.get('/douyin/user/', {
            params: {
              user_id: userId,
              token: token
            }
          })

          if (userRes.data && userRes.data.user) {
            commit('SET_USER', userRes.data.user)
          } else {
            console.warn('获取用户信息返回无效数据:', userRes.data)
            throw new Error('获取用户信息失败')
          }
        } catch (userError) {
          console.error('登录后获取用户信息失败', userError)
          // 这里不抛出错误，因为用户已经登录成功，我们不希望因为获取用户信息失败而阻止用户登录
          // 但我们需要确保在界面上通知用户
        }

        return {
          ...res.data,
          user_id: userId // 确保返回给其他组件的也是字符串形式
        }
      } catch (error) {
        console.error('登录失败', error)
        // 确保清除任何可能已部分设置的凭证
        commit('CLEAR_TOKEN')
        localStorage.removeItem('user_id')
        throw error
      }
    },

    // 用户注册
    async register({ commit }, { username, password }) {
      try {
        const params = new URLSearchParams()
        params.append('username', username)
        params.append('password', password)

        const res = await axios.post('/douyin/user/register/', params, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        })

        // 如果注册成功且返回了用户ID，确保以字符串形式处理
        if (res.data && res.data.status_code === 0) {
          // 处理user_id，确保以字符串形式保存，避免精度丢失
          let userId = res.data.user_id;

          // 先检查是否已经是字符串
          if (typeof userId === 'string') {
            console.log('注册返回的用户ID已经是字符串:', userId);
          } else if (userId) {
            console.log('注册返回的原始用户ID类型:', userId, typeof userId);

            try {
              // 直接转换为字符串
              userId = String(userId);
              console.log('转换后的用户ID:', userId);
            } catch (e) {
              console.error('转换用户ID出错:', e);
              // 退回到基本的转换方法
              userId = String(res.data.user_id);
            }
          }

          return {
            ...res.data,
            user_id: userId
          };
        }

        return res.data;
      } catch (error) {
        console.error('注册失败', error)
        throw error
      }
    },

    // 退出登录
    logout({ commit }) {
      commit('CLEAR_TOKEN')
      commit('SET_USER', null)
      localStorage.removeItem('user_id')
      localStorage.removeItem('token')
      // 清除所有可能与用户相关的本地存储项
      const keysToRemove = []
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i)
        if (key && (
          key.startsWith('user_') ||
          key.includes('token') ||
          key.includes('auth') ||
          key.includes('login')
        )) {
          keysToRemove.push(key)
        }
      }
      keysToRemove.forEach(key => localStorage.removeItem(key))

      // 重置vuex中的用户相关状态
      commit('SET_VIDEOS', [])
      commit('SET_CURRENT_VIDEO_INDEX', 0)
    },

    // 获取视频流
    async fetchVideos({ commit, state }) {
      try {
        const latestTime = Date.now()
        const params = {
          latest_time: latestTime
        }
        if (state.token) {
          params.token = state.token
        }

        const res = await axios.get('/douyin/feed', { params })

        // 过滤掉已观看的视频
        const filteredVideos = res.data.video_list.filter(
          video => !state.viewedVideos.has(video.id)
        )

        // 按点赞数排序
        filteredVideos.sort((a, b) => b.favorite_count - a.favorite_count)

        commit('SET_VIDEOS', filteredVideos)
        commit('SET_CURRENT_VIDEO_INDEX', 0)
        return filteredVideos
      } catch (error) {
        console.error('获取视频失败', error)
        throw error
      }
    },

    // 视频点赞/取消点赞
    async toggleFavorite({ commit, state }, { videoId, actionType }) {
      try {
        console.log('Vuex Store 点赞操作 - 视频ID:', videoId, 'Action类型:', actionType);

        if (!state.token) {
          throw new Error('请先登录')
        }

        const params = new URLSearchParams()
        params.append('token', state.token)
        params.append('video_id', videoId.toString())
        params.append('action_type', actionType)

        await axios.post('/douyin/favorite/action/', params, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        })

        // 根据actionType确定是点赞还是取消点赞
        // actionType为1表示点赞，为2表示取消点赞
        const isFavorite = actionType === 1
        console.log('Vuex Store 更新状态 - 视频ID:', videoId, '设置为已点赞:', isFavorite);
        commit('TOGGLE_FAVORITE', { videoId, isFavorite })
      } catch (error) {
        console.error('点赞操作失败', error)
        throw error
      }
    },

    // 获取用户视频列表
    async fetchUserVideos({ state }, userId) {
      try {
        if (!state.token) {
          throw new Error('请先登录')
        }

        const res = await axios.get('/douyin/publish/list/', {
          params: {
            token: state.token,
            user_id: userId.toString()  // 确保用户ID作为字符串传递
          }
        })

        return res.data.video_list
      } catch (error) {
        console.error('获取用户视频失败', error)
        throw error
      }
    },

    // 获取当前登录用户信息
    async fetchUserInfo({ commit, state, dispatch }) {
      try {
        if (!state.token) {
          throw new Error('请先登录')
        }

        // 尝试从localStorage获取用户ID
        const userId = localStorage.getItem('user_id')
        if (!userId) {
          // 无法获取用户ID，清除token并引导用户重新登录
          dispatch('logout')
          throw new Error('无法获取用户ID，请重新登录')
        }

        try {
          // 确保用户ID作为字符串传递，避免精度丢失
          const response = await axios.get('/douyin/user/', {
            params: {
              user_id: userId.toString(),  // 明确转为字符串
              token: state.token
            }
          })

          if (response.data && response.data.user) {
            commit('SET_USER', response.data.user)
            return response.data.user
          } else {
            // 找不到用户信息，可能是后端返回了空数据
            dispatch('logout')
            throw new Error(response.data?.status_msg || '获取用户信息失败')
          }
        } catch (error) {
          // 捕获请求错误（如404、500等）
          dispatch('logout')
          if (error.response && error.response.data && error.response.data.status_msg) {
            throw new Error(error.response.data.status_msg)
          } else if (error.message) {
            throw new Error(error.message)
          } else {
            throw new Error('网络错误，请重新登录')
          }
        }
      } catch (error) {
        console.error('获取用户信息失败:', error)
        throw error
      }
    },

    // 从localStorage获取用户ID（实际上这个方法已经不需要了，但为了保持代码结构，我们保留它）
    getUserIdFromToken({ state }) {
      if (!state.token) {
        return null
      }

      return localStorage.getItem('user_id')
    }
  }
}) 